home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / incoming / jstools-.6v3 / jstools- / jstools-tk3.6v3.0 / lib / jtextemacs.tcl < prev    next >
Encoding:
Text File  |  1995-02-05  |  7.9 KB  |  281 lines

  1. # jtextemacs.tcl - additional procedures for Emacs-like Text bindings
  2. # Copyright 1992-1994 by Jay Sekora.  All rights reserved, except 
  3. # that this file may be freely redistributed in whole or in part 
  4.  
  5. # TO DO:
  6. # ^L
  7. # sentence-manipulation stuff
  8. # case change commands, transposition commands
  9. # commands to do with mark?
  10. # word deletion - fix to use buffer
  11. # generalise movement to copying-to-cutbuffer and deletion
  12. # IMPROVE ENTRY BINDINGS
  13. # literal-insert for entry
  14.  
  15. ######################################################################
  16. # j:tb:emacs_init t - set emacs bindings up for widget $t (possibly "Text")
  17. ######################################################################
  18.  
  19. proc j:tb:emacs_init { {t Text} } {
  20.   global j_teb
  21.   set j_teb(cutbuffer) {}
  22.   set j_teb(dragscroll,txnd) 0
  23.   set j_teb(dragscroll,delay) 50
  24.   set j_teb(scanpaste_time) 0
  25.   set j_teb(scanpaste_paste) 1
  26.   
  27.   set j_teb(keymap,$t) emacs-normal
  28.   
  29.   # in tk4, we need to make sure tkTextBind is called _before_
  30.   #   j:tb:key_bind!
  31.   j:tk4 {tkTextBind Enter}
  32.   
  33.   j:tb:key_bind $t
  34.   j:tb:mouse_bind $t
  35.   
  36.   j:tkb:mkmap Text emacs-normal emacs-normal {
  37.     {Control-slash        j:tb:select_all}
  38.     {Control-backslash        j:tb:clear_selection}
  39.     
  40.     {Delete            j:tkb:delete_left}
  41.     {BackSpace            j:tkb:delete_left}
  42.     {Return            j:tkb:insert_newline}
  43.     
  44.     {Control-d            j:tkb:delete_right}
  45.     
  46.     {Up                j:tkb:up}
  47.     {Down            j:tkb:down}
  48.     {Left            j:tkb:left}
  49.     {Right            j:tkb:right}
  50.     
  51.     {Control-p            j:tkb:up}
  52.     {Control-n            j:tkb:down}
  53.     {Control-b            j:tkb:left}
  54.     {Control-f            j:tkb:right}
  55.     
  56.     {Home            j:tkb:bol}
  57.     {End            j:tkb:eol}
  58.     
  59.     {Control-a            j:tkb:bol}
  60.     {Control-e            j:tkb:eol}
  61.     
  62.     {Next            j:tkb:scroll_down}
  63.     {Prior            j:tkb:scroll_up}
  64.     
  65.     {Control-v            j:tkb:scroll_down}
  66.     
  67.     {Control-k            j:tkb:e:kill_line}
  68.     {Control-w            j:tkb:e:kill_region}
  69.     {Control-y            j:tkb:e:yank}
  70.  
  71.     {Control-i            j:tkb:self_insert}
  72.     {Control-j            j:tkb:self_insert}
  73.     {Control-h            j:tkb:delete_left}
  74.     
  75.     {Control-space        j:tkb:e:set_mark_command}
  76.     {Control-at            j:tkb:e:set_mark_command}
  77.     
  78.     {Control-g            j:tkb:clear_count}
  79.     
  80.     {1                j:tkb:self_insert_digit}
  81.     {2                j:tkb:self_insert_digit}
  82.     {3                j:tkb:self_insert_digit}
  83.     {4                j:tkb:self_insert_digit}
  84.     {5                j:tkb:self_insert_digit}
  85.     {6                j:tkb:self_insert_digit}
  86.     {7                j:tkb:self_insert_digit}
  87.     {8                j:tkb:self_insert_digit}
  88.     {9                j:tkb:self_insert_digit}
  89.     {0                j:tkb:self_insert_digit}
  90.     
  91.     {Control-u            j:tkb:e:generic_arg}
  92.     
  93.     {Control-q            j:tkb:new_mode emacs-literal}
  94.     {Control-x            j:tkb:new_mode emacs-control-x}
  95.     {Escape            j:tkb:new_mode emacs-escape}
  96.     
  97.     {Control-DEFAULT        j:tb:no_op}
  98.     {DEFAULT            j:tkb:self_insert}
  99.     {Shift-DEFAULT        j:tkb:self_insert}
  100.   }
  101.   
  102.   j:tkb:mkmap Text emacs-literal emacs-normal {
  103.     {DEFAULT            j:tkb:self_insert}
  104.     {Shift-DEFAULT        j:tkb:self_insert}
  105.     {Control-DEFAULT        j:tkb:self_insert}
  106.     {Meta-DEFAULT        j:tkb:self_insert}
  107.   }
  108.   
  109.   j:tkb:mkmap Text emacs-control-x emacs-normal {
  110.     {Control-g            j:tkb:clear_count}
  111.     {Control-x            j:tkb:e:exchange_point_and_mark}
  112.     
  113.     {DEFAULT            j:tkb:clear_count}
  114.     {Shift-DEFAULT        j:tkb:clear_count}
  115.     {Control-DEFAULT        j:tkb:clear_count}
  116.     {Meta-DEFAULT        j:tkb:clear_count}
  117.   }
  118.   
  119.   j:tkb:mkmap Text emacs-escape emacs-normal {
  120.     {less            j:tkb:bof}
  121.     {greater            j:tkb:eof}
  122.     {b                j:tkb:word_left}
  123.     {f                j:tkb:word_right}
  124.     {v                j:tkb:scroll_up}
  125.     {Delete            j:tkb:delete_left_word}
  126.     {BackSpace            j:tkb:delete_left_word}
  127.     {d                j:tkb:delete_right_word}
  128.     
  129.     {1                j:tkb:start_number}
  130.     {2                j:tkb:start_number}
  131.     {3                j:tkb:start_number}
  132.     {4                j:tkb:start_number}
  133.     {5                j:tkb:start_number}
  134.     {6                j:tkb:start_number}
  135.     {7                j:tkb:start_number}
  136.     {8                j:tkb:start_number}
  137.     {9                j:tkb:start_number}
  138.     {0                j:tkb:start_number}
  139.     
  140.     {Control-g            j:tkb:clear_count}
  141.     
  142.     {DEFAULT            j:tb:no_op}
  143.     {Shift-DEFAULT        j:tb:no_op}
  144.     {Control-DEFAULT        j:tb:no_op}
  145.     {Meta-DEFAULT        j:tb:no_op}
  146.   }
  147. }
  148.  
  149. ######################################################################
  150. # j:tkb:e:generic_arg - start generic argument
  151. #   kind of clumsy: set repeat count to four, or multiply by four
  152. ######################################################################
  153.  
  154. proc j:tkb:e:generic_arg { W args } {
  155.   global j_teb
  156.   
  157.   # set up prefix/repeat information if this widget hasn't been used yet
  158.   if {! [info exists j_teb(prefix,$W)]} {
  159.     set j_teb(prefix,$W) 0
  160.   }
  161.   if {! [info exists j_teb(repeat_count,$W)]} {
  162.     set j_teb(repeat_count,$W) 1
  163.   }
  164.  
  165.   if {$j_teb(prefix,$W) == 1 && $j_teb(repeat_count,$W) == 0} {
  166.     set j_teb(repeat_count,$W) 16        ;# ^U^U -> 4*4
  167.     return
  168.   }
  169.   if {$j_teb(prefix,$W) == 0} {
  170.     set j_teb(prefix,$W) 1
  171.     set j_teb(repeat_count,$W) 0        ;# special; -> 4 in repeatable
  172.     return
  173.   }
  174.   set j_teb(repeat_count,$W) [expr {$j_teb(repeat_count,$W)*4}]
  175. }
  176.  
  177. ######################################################################
  178. ###  TEXT EMACS DELETION COMMANDS
  179. ######################################################################
  180.  
  181. # j:tkb:e:kill_line W K A - delete insert to end-of-line, setting cutbuffer
  182. #   (arg handled by called procedure)
  183. proc j:tkb:e:kill_line { W K A } {
  184.   global j_teb
  185.   set j_teb(modified,$W) 1
  186.   
  187.   # set up prefix/repeat information if this widget hasn't been used yet
  188.   if {! [info exists j_teb(prefix,$W)]} {
  189.     set j_teb(prefix,$W) 0
  190.   }
  191.   if {! [info exists j_teb(repeat_count,$W)]} {
  192.     set j_teb(repeat_count,$W) 1
  193.   }
  194.  
  195.   # Append to cutbuffer if previous command was line-kill; otherwise
  196.   #   start with new cutbuffer:
  197.   set my_name [lindex [info level 0] 0]
  198.   if {! [string match $my_name $j_teb(last_command,$W)]} {
  199.     set j_teb(cutbuffer) {}
  200.   }
  201.   
  202.   # special-case prefix == 1 and repeat_count == 0 for Emacs ^U^U:
  203.   #
  204.   if {$j_teb(prefix,$W) == 1 && $j_teb(repeat_count,$W) == 0} {
  205.     set j_teb(repeat_count,$W) 4
  206.   }
  207.   
  208.   # if no argument, DON'T kill "\n" unless it's only thing at insert
  209.   #
  210.   if {$j_teb(repeat_count,$W) < 2} {
  211.     j:tkb:clear_count $W            ;# in case it's eg -1
  212.     if {[$W index insert] == [$W index {insert lineend}]} then {
  213.       append j_teb(cutbuffer) [$W get insert]
  214.       j:text:delete $W insert {insert + 1 char}
  215.     } else {
  216.       append j_teb(cutbuffer) [$W get insert {insert lineend}]
  217.       j:text:delete $W insert {insert lineend}
  218.     }
  219.   } else {
  220.     # with argument, kill that many lines (including "\n")
  221.     j:tkb:repeatable {
  222.       append j_teb(cutbuffer) [$W get insert {insert lineend + 1 char}]
  223.       j:text:delete $W insert {insert lineend + 1 char}
  224.     } $W
  225.   }
  226.   
  227.   set j_teb(repeat_count,$W) 1
  228. }
  229.  
  230. # j:tkb:e:kill_region W K A - delete selected region, setting cutbuffer
  231. ###   emacs region shouldn't be conflated with Text selection!
  232. proc j:tkb:e:kill_region { W K A } {
  233.   global j_teb
  234.   set j_teb(modified,$W) 1
  235.  
  236.   j:tkb:clear_count $W
  237.  
  238.   set j_teb(cutbuffer) {}
  239.   catch {
  240.     set j_teb(cutbuffer) [$W get sel.first sel.last]
  241.     j:text:delete $W sel.first sel.last
  242.   }
  243. }
  244.  
  245. # j:tkb:e:yank W K A - insert contents of cutbuffer
  246. ###   handling of argument needs changed---not count, but not ignored
  247. proc j:tkb:e:yank { W K A } {
  248.   global j_teb
  249.  
  250.   j:tkb:clear_count $W
  251.   
  252.   j:text:insert_string $W $j_teb(cutbuffer)
  253. }
  254.  
  255. ######################################################################
  256. ###  TEXT EMACS MARK COMMANDS
  257. ######################################################################
  258.  
  259. # j:tkb:e:set_mark_command W K A - set emacs mark at current insert point
  260. proc j:tkb:e:set_mark_command { W K A } {
  261.   $W mark set emacs_mark insert
  262. }
  263.  
  264. # j:tkb:e:exchange_point_and_mark W K A - swap insert point and emacs mark
  265. proc j:tkb:e:exchange_point_and_mark { W K A } {
  266.   if {[lsearch [$W mark names] emacs_mark] != -1} {
  267.     set mark [$W index emacs_mark]
  268.     $W mark set emacs_mark insert
  269.     j:tb:move $W $mark
  270.   } else {
  271.     error "The mark is not set in text widget $W."
  272.   }
  273. }
  274.  
  275. # deprecated alias for backwards-compatibility:
  276.  
  277. proc j:tb:emacs_bind { W } {
  278.   j:tb:emacs_init $W
  279. }
  280.